package com.example.demo.interceptor;

import com.example.demo.util.TraceIdUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Controller响应拦截器
 * 拦截所有Controller层的接口，统一封装返回结果为Result格式
 * 负责生成和清除链路追踪ID（TraceId）
 * 注意：异常捕获由GlobalExceptionHandler处理
 * 
 * @author zhang
 * @date 2024
 */
@Component
public class ResultInterceptor implements HandlerInterceptor {
    
    private static final Logger logger = LoggerFactory.getLogger(ResultInterceptor.class);
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 检查是否已有TraceId（由HttpMethodFilter生成）
        String traceId = TraceIdUtil.getTraceId();
        if (traceId == null) {
            // 如果没有TraceId，生成一个（兜底机制）
            traceId = TraceIdUtil.generateTraceId();
            TraceIdUtil.setTraceId(traceId);
            response.setHeader("X-Trace-Id", traceId);
        }
        
        // 将TraceId放入MDC，用于日志输出
        MDC.put("traceId", traceId);
        
        // 记录请求开始时间
        long startTime = System.currentTimeMillis();
        request.setAttribute("_START_TIME_", startTime);
        
        // 记录请求信息（会在日志头部自动显示TraceId）
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            logger.info("请求处理开始: {} - {}", request.getRequestURI(), handlerMethod.getMethod().getName());
        }
        
        return true;
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        try {
            // 获取TraceId并确保在响应头中设置（即使已经设置，再次确保）
            String traceId = TraceIdUtil.getTraceId();
            if (traceId != null) {
                response.setHeader("X-Trace-Id", traceId);
            }
            
            // 计算请求耗时
            Long startTime = (Long) request.getAttribute("_START_TIME_");
            if (startTime != null) {
                long duration = System.currentTimeMillis() - startTime;
                logger.info("请求处理完成: {} - 耗时: {}ms", request.getRequestURI(), duration);
            }
            
            // 记录请求结果
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                if (ex != null) {
                    logger.error("请求处理异常: {} - {}", request.getRequestURI(), ex.getMessage(), ex);
                } else {
                    logger.debug("请求处理成功: {} - {}", request.getRequestURI(), handlerMethod.getMethod().getName());
                }
            }
        } finally {
            // 注意：TraceId的清除由HttpMethodFilter负责，这里只清除MDC
            // TraceIdUtil.removeTraceId();
            MDC.clear(); // 清除MDC中所有的键值对
        }
        
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

